package qing.controller;

import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.aop.interceptor.SimpleTraceInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializeFilter;
import com.alibaba.fastjson.serializer.SimplePropertyPreFilter;

import qing.entity.PageJson;
import qing.entity.ValidJson;
import qing.common.u.StringUtils;
import qing.common.query.DuplicateValid;
import qing.common.query.Page;
import qing.common.query.PageableDefaults;
import qing.common.query.PropertyPreFilterable;
import qing.common.query.Queryable;
import net.sf.ehcache.search.expression.Criteria;
import qing.service.ICommonService;
import qing.common.u.MyBeanUtils;
import qing.common.u.ObjectUtils;
import qing.entity.AbstractEntity;
import qing.entity.AjaxJson;



public  abstract class CommonController<T extends AbstractEntity<ID>,ID extends Serializable>  extends BaseBeanController<T> {

	@Autowired
	protected ICommonService<T> idao;

	private String entityname=entityClass.getSimpleName();
	private String entitynameLower=entityname.toLowerCase();
	/**
	 * 设置基础service
	 *
	 * @param baseService
	 */
/*	@Autowired
	public void setCommonService(ICommonService<T> commonService) {
		this.idao = commonService;
	}*/

	public T get(ID id) {
		if (!ObjectUtils.isNullOrEmpty(id)) {
			return idao.get(id);
		} else {
			return newModel();
		}
	}
	

	/**
	 * list 运行之前
	 * 
	 * @param model
	 * @param request
	 * @param response
	 */
	public void preList(Model model, HttpServletRequest request, HttpServletResponse response) {
	}

	//@RequiresMethodPermissions("list")
	@RequestMapping(method = RequestMethod.GET)
	public String list(Model model, HttpServletRequest request, HttpServletResponse response) {
		preList(model, request, response);
		System.out.println("prilist");
		return display("list");
	}

	/**
	 * 在异步获取数据之前
	 * 
	 * @param model
	 * @param request
	 * @param response
	 */
	public void preAjaxList(Queryable queryable, DetachedCriteria detachedCriteria, HttpServletRequest request,
			HttpServletResponse response) {

	}

	/**
	 * 根据页码和每页记录数，以及查询条件动态加载数据
	 * 
	 * @param request
	 * @param response
	 * @throws IOException
	 */
	@RequestMapping(value = "ajaxList", method = { RequestMethod.GET, RequestMethod.POST })
	@PageableDefaults(sort = "id=desc")
	private void ajaxList(Queryable queryable,PropertyPreFilterable propertyPreFilterable, HttpServletRequest request,
			HttpServletResponse response) throws IOException {
		DetachedCriteria detachedCriteria = DetachedCriteria.forClass(entityClass);
		preAjaxList(queryable, detachedCriteria, request, response);
		propertyPreFilterable.addQueryProperty("id");
		SerializeFilter filter = propertyPreFilterable.constructFilter(entityClass);
		Page<T>  pages=idao.list(queryable, detachedCriteria);
		PageJson<T> pagejson = new PageJson<T>(pages);
		String content = JSON.toJSONString(pagejson, filter);
		StringUtils.printJson(response, content);
	}

	public String showView(T entity, Model model, HttpServletRequest request, HttpServletResponse response) {
		return "";
	}

	/**
	 * 
	 * @title: _view
	 * @description: 查看
	 * @param model
	 * @param id
	 * @param request
	 * @param response
	 * @return
	 * @return: String
	 */
	@RequestMapping(value = "/{id}", method = RequestMethod.GET)
	public String _view(Model model, @PathVariable("id") ID id, HttpServletRequest request,
			HttpServletResponse response) {
		T entity = get(id);
		showUpdate(entity, model, request, response);
		model.addAttribute("data", entity);
		String showView = showView(newModel(), model, request, response);
		if (!StringUtils.isEmpty(showView)) {
			return display(showView);
		}
		return display("edit");
	}

	public void preEdit(T entity, Model model, HttpServletRequest request, HttpServletResponse response) {

	}

	public String showCreate(T entity, Model model, HttpServletRequest request, HttpServletResponse response) {
		return "";
	}

	@RequestMapping(value = "create", method = RequestMethod.GET)
	public String _showCreate(Model model, HttpServletRequest request, HttpServletResponse response) {
		preEdit(newModel(), model, request, response);
		String creteaView = showCreate(newModel(), model, request, response);
		if (!model.containsAttribute("data")) {
			model.addAttribute("data", newModel());
		}
		if (!StringUtils.isEmpty(creteaView)) {
			return creteaView;
		}
		return display("edit");
	}

	@RequestMapping(value = "create", method = RequestMethod.POST)
	@ResponseBody
	public AjaxJson create(Model model, @Valid @ModelAttribute("data") T entity, BindingResult result,
			HttpServletRequest request, HttpServletResponse response) {
		return doSave(entity, request, response, result);
	}

	public String showUpdate(T entity, Model model, HttpServletRequest request, HttpServletResponse response) {
		return "";
	}

	@RequestMapping(value = "{id}/update", method = RequestMethod.GET)
	public String _showUpdate(@PathVariable("id") ID id, Model model, HttpServletRequest request,
			HttpServletResponse response) {
		T entity = get(id);
		preEdit(entity, model, request, response);
		model.addAttribute("data", entity);
		String updateView = showUpdate(newModel(), model, request, response);
		if (!StringUtils.isEmpty(updateView)) {
			return updateView;
		}
		return display("edit");
	}

	@RequestMapping(value = "{id}/update", method = RequestMethod.POST)
	@ResponseBody
	public AjaxJson update(Model model, @Valid @ModelAttribute("data") T entity, BindingResult result,
			HttpServletRequest request, HttpServletResponse response) {
		return doSave(entity, request, response, result);
	}

	/**
	 * 保存数据之前
	 * 
	 * @param entity
	 * @param request
	 * @param response
	 */
	public void preSave(T entity, HttpServletRequest request, HttpServletResponse response) {
	}

	@RequestMapping(value = "/save", method = RequestMethod.POST)
	@ResponseBody
	public AjaxJson doSave(T entity, HttpServletRequest request, HttpServletResponse response,
			BindingResult result) {
		AjaxJson ajaxJson = new AjaxJson();
		ajaxJson.success("保存成功");
		if (hasError(entity, result)) {
			// 错误提示
			String errorMsg = errorMsg(result);
			if (!StringUtils.isEmpty(errorMsg)) {
				ajaxJson.fail(errorMsg);
			} else {
				ajaxJson.fail("保存失败");
			}
			return ajaxJson;
		}
		try {
			preSave(entity, request, response);
			if (ObjectUtils.isNullOrEmpty(entity.getId())) {
				idao.save(entity);
			} else {
				// FORM NULL不更新
				T oldEntity = idao.get(entity.getId());
				MyBeanUtils.copyBeanNotNull2Bean(entity, oldEntity);
				idao.update(oldEntity);
			}
			afterSave(entity, request, response);
		} catch (Exception e) {
			e.printStackTrace();
			ajaxJson.fail("保存失败!<br />原因:" + e.getMessage());
		}
		return ajaxJson;
	}

	/**
	 * 保存数据之后
	 * 
	 * @param entity
	 * @param request
	 * @param response
	 */
	public void afterSave(T entity, HttpServletRequest request, HttpServletResponse response) {
	}

	@RequestMapping(value = "{id}/delete", method = RequestMethod.POST)
	@ResponseBody
	public AjaxJson delete(@PathVariable("id") ID id) {
		AjaxJson ajaxJson = new AjaxJson();
		ajaxJson.success("删除成功");		
		try {
			idao.deleteById(id);
		} catch (Exception e) {
			e.printStackTrace();
			ajaxJson.fail("删除失败");
		}
		return ajaxJson;
	}

	@RequestMapping(value = "batch/delete", method = { RequestMethod.GET, RequestMethod.POST })
	@ResponseBody
	public AjaxJson batchDelete(@RequestParam(value = "ids", required = false) ID[] ids) {
		AjaxJson ajaxJson = new AjaxJson();
		ajaxJson.success("删除成功");		
		try {
			List<ID> idList = java.util.Arrays.asList(ids);
			idao.batchDeleteById(idList);
		} catch (Exception e) {
			e.printStackTrace();
			ajaxJson.fail("删除失败");
		}
		return ajaxJson;
	}

	@RequestMapping(value = "validate", method = { RequestMethod.GET, RequestMethod.POST })
	@ResponseBody
	public ValidJson validate(DuplicateValid duplicateValid, HttpServletRequest request) {
		ValidJson validJson = new ValidJson();
		Boolean valid = Boolean.FALSE;
		try {
			valid = idao.doValid(duplicateValid);

			if (valid) {
				validJson.setStatus("y");
				validJson.setInfo("验证通过!");
			} else {
				validJson.setStatus("n");
				if (!StringUtils.isEmpty(duplicateValid.getErrorMsg())) {
					validJson.setInfo(duplicateValid.getErrorMsg());
				} else {
					validJson.setInfo("当前信息重复!");
				}
			}
		} catch (Exception e) {
			validJson.setStatus("n");
			validJson.setInfo("验证异常，请检查字段是否正确!");
		}
		return validJson;
	}
	 
	
	@RequestMapping("list")
	public String showlist(Map<String, Object> map) {
		map.put("list", idao.list());
		//return "cms/article/"+entitynameLower+"list";
		 System.out.println("prilist");
			return display("list");
	}
	
	@ResponseBody
	@RequestMapping("bind")
	public String showlist(int filetype) {		
		Criterion ces=Restrictions.eq("filetype", filetype);
		SimplePropertyPreFilter filter = new SimplePropertyPreFilter(entityClass, "id,title"); 
		List<T> list=idao.listByCriterion(ces);
		String json = JSON.toJSONString(list, filter);
		return json;
	}
	
	//绑定模型
	@ModelAttribute
	public void model(@RequestParam(value = "id", required = false) String id, Map<String, Object> map) {
		if (id != null) {
			System.out.println("绑定模型：ModelAttribute");
			map.put(entitynameLower, idao.get(id));
		}
	}
	
//添加回显
	@RequestMapping(value = "add")
	public String addini(Map<String, Object> map) {
		map.put(entitynameLower,newModel());
		return display("add");
	}
 //提交新增
	@RequestMapping(value = "add", method = RequestMethod.POST)
	public String add(T u,HttpServletRequest request, Map<String, Object> map) {	
		System.out.println("新增保存数据："+u);
		// Person user=(Person)request.getSession().getAttribute("user");		 
		//u.setAdduser(user.getUsername());		
		idao.save(u);
		return "redirect:list";
	}
//修改初始化
	@RequestMapping(value = "add/{id}")
	public String editini(@PathVariable("id") String id, Map<String, Object> map) {
		map.put(entitynameLower, idao.get(id));		
		return display("add");
	}  
//提交修改
	@RequestMapping(value = "add", method = RequestMethod.PUT)
	public String edit(@Valid T u, BindingResult result, HttpServletRequest request, Map<String, Object> map) {
		System.out.println("开始修改，并重定向……" + u.toString());
	/*	if (result.getErrorCount() > 0) {
			// 打印出错误信息，调试用
			for (FieldError error : result.getFieldErrors()) {
				System.out.println(error.getField() + ":" + error.getDefaultMessage());
			}

			// 若验证出错，转向错误页面,初始化页面绑定数据
			map.put(entitynameLower,u);
			return "add"+entitynameLower;
		}*/
				
		idao.update(u);
		return "redirect:list";
	}
//删除
	@RequestMapping(value = "del/{id}", method = RequestMethod.DELETE)
	public String delete0(@PathVariable("id") String id) {
		System.out.println("dele:" + id);
		idao.deleteById(id);
		return "redirect:../list";
	}



	@ResponseBody
	@RequestMapping("jsonlist")
	public List<T> showlistjson(Map<String, Object> map) {
		return idao.list();
		
	}

	 //提交新增
		@ResponseBody
		@RequestMapping(value = "jsonadd", method = RequestMethod.POST)
		public String add(@RequestParam(value = "id", required = false) String id,T model) {
			idao.save(model);			
			return "{\"status\":1,\"msg\":\"\"}";
		}
				
		@RequestMapping(value = "jsonadd", method = RequestMethod.PUT,produces="application/json;charset=UTF-8")
		public  @ResponseBody Object edit(T model) {			
				idao.update(model);		
				System.out.println("put:"+model);
			JSONObject js = new JSONObject();
	        js.put("status", 1);
	        return js;
		}
		
	//删除
		@RequestMapping(value = "jsondel/{id}", method = RequestMethod.DELETE,produces="application/json;charset=UTF-8")
		public @ResponseBody Object deletejson(@PathVariable("id") String id) {
			idao.deleteById(id);
			JSONObject js = new JSONObject();
	        js.put("status", 1);
	        return js;
		}
		
		
	

}
